package com.lmx.cloud;

import java.util.ArrayList;
import java.util.Date;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.logging.log4j.core.util.FileWatcher;

import java.text.SimpleDateFormat;
import com.lmx.bean.FileUnit;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import net.sf.json.JSONObject;

import com.lmx.creceive.*;
import com.lmx.util.ConfigUtil;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

// 真正的文件上传模块，调用upload就直接上传
public class FileUploader {
  private static int index = 0;
  
  private static MinioClient client;
  
  public static String bucket = "data";
  //udp
  public static DatagramSocket datagramSocket;
  // public static String bucket = "hitwhtest";
  private static  String record_file="log.txt"; 
  private static PrintWriter pw=null;
  private static final String sendAddress="10.0.0.229";
  // private static final String sendAddress="192.168.1.105";
  private static ArrayList<String> buckNameList=new ArrayList<>();
  private static final int sendPort=9996;
  
public static void log(String str){
	try {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date1 = formatter.format(date);
        FileOutputStream fos = new FileOutputStream(record_file,true);
        OutputStreamWriter osw = new OutputStreamWriter(fos);
        pw = new PrintWriter(osw);
        pw.println(str+"\n"+date1);
	}catch (FileNotFoundException e) {
        e.printStackTrace();
    }finally {
        pw.close();
    }
}

  
  public static void init() throws Exception 
  {
 
        if (client == null) {
          client = MinioClient.builder()
        .endpoint(ConfigUtil.getConfig("cloud.url"))
        .credentials(ConfigUtil.getConfig("cloud.access_key"),ConfigUtil.getConfig("cloud.secret_key"))
        .build();
        // client = new MinioClient(ConfigUtil.getConfig("cloud.url"),
        // 9011,
        // ConfigUtil.getConfig("cloud.access_key"),
        // ConfigUtil.getConfig("cloud.secret_key"),
        // false
        // );

        }
        boolean isExist = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        if (!isExist) {
          client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
          
        }
      
  }
  public static void InitSocket() throws IOException
  {
      datagramSocket = new DatagramSocket(9998);
      datagramSocket.setSoTimeout(5000);
  }
   public static void CloseSocket() throws IOException
  {
      datagramSocket.close();
  }
  public static void udpSend(String question) throws Exception
  {
      byte[] buf = question.getBytes();
      DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName(sendAddress),sendPort); //封装返回给客户端的数据
      datagramSocket.send(sendPacket);
  }
  public static String udpReceive(int size) throws Exception
  {
      byte[] buffer = new byte[size];
      DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
      datagramSocket.receive(packet);
      String str=new String(packet.getData(), 0,packet.getLength(), StandardCharsets.UTF_8);
      return str;
  }
  public static void udpSend(String question,String sendAddress,int sendPort) throws Exception
  {
      byte[] buf = question.getBytes();
      DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, InetAddress.getByName(sendAddress),sendPort); //封装返回给客户端的数据
      datagramSocket.send(sendPacket);
  }
  
  public static void receive() throws Exception {

    // int[] x=myReceive.canreceive();
    // datagramSocket = new DatagramSocket(9998);
    // int[] x={1,2,3,20,5,6,7,8,9,10,11,12,25};
      
      
      try{
        CloseSocket();
      }catch(Exception e){
        System.out.println("socket already closed");
      }
      InitSocket();
      //图像数据
      String dataDepth=null;
      String dataRGB=null;
      String dataCan=null;
      String dataWatch=null;
      while(true)
      {
        //传输
        
        String question = "start";
        
        
        //通过套接字向客户端发送数据
        try{
          udpSend(question);
          String str=udpReceive(8);
          if(!str.equals("ok"))
              continue;
        }catch(SocketTimeoutException e){
          log("image not connect");
          continue;
        }
      
        try{
            System.out.println("send finished\n");//console 输出
            question = "rgb";
            udpSend(question);
            //接收RGB图像
            long dataSize=Long.parseLong(udpReceive(8));
            long receivedSize = 0;
            byte[] dataTotal = new byte[0];
            long RGBtime=dataSize/1024;
            if(dataSize%1024!=0)
              RGBtime+=1;
            while (RGBtime!=0) {
                RGBtime--;
                udpSend("ok");
                byte[] data1 = new byte[1024];
                DatagramPacket packet = new DatagramPacket(data1, data1.length);
                datagramSocket.receive(packet);
                receivedSize += packet.getLength();
                byte[] newData = new byte[dataTotal.length + packet.getLength()];
                System.arraycopy(dataTotal, 0, newData, 0, dataTotal.length);
                System.arraycopy(packet.getData(), 0, newData, dataTotal.length, packet.getLength());
                dataTotal = newData;
                
                // System.out.println("receivesize:"+receivedSize+"\tdatasize:"+dataSize+"\n");
            }
            System.out.println("receive RGB finished\n");//console 输出
            question = "depth";
            udpSend(question);
            dataRGB=new String(dataTotal, 0,dataTotal.length, StandardCharsets.UTF_8);
            //接收深度
            // data+="\ndepth\n";
            long dataSize1=Long.parseLong(udpReceive(8));
            
            long receivedSize1 = 0;
            byte[] dataTotal1 = new byte[0];
            long Depthtime=dataSize1/1024;
            if(Depthtime%1024!=0)
              Depthtime+=1;
            while (Depthtime!=0) {
                Depthtime--;
                udpSend("ok");
                byte[] data1 = new byte[1024];
                DatagramPacket packet1 = new DatagramPacket(data1, data1.length);
                datagramSocket.receive(packet1);
                receivedSize1 += packet1.getLength();
                byte[] newData1 = new byte[dataTotal1.length + packet1.getLength()];
                System.arraycopy(dataTotal1, 0, newData1, 0, dataTotal1.length);
                System.arraycopy(packet1.getData(), 0, newData1, dataTotal1.length, packet1.getLength());
                dataTotal1 = newData1;
                // System.out.println("receivesize:"+receivedSize1+"\tdatasize:"+dataSize1+"\n");
            }
            System.out.println("receive depth finished\n");//console 输出
            dataDepth=new String(dataTotal1, 0,dataTotal1.length, StandardCharsets.UTF_8);
            break;//退出图像循环
          }catch(SocketTimeoutException e){
            log("image not accept");
            e.printStackTrace();
            udpSend("close");
            continue;
          }
        
      }
      // data+="\ncan\n";
      // can
      dataCan="";
      try{
        int []x=new receive().canreceive();
        String strArray[] = new String[x.length];
 
        for (int i = 0; i < x.length; i++)
            strArray[i] = String.valueOf(x[i]);
        dataCan+=strArray;

      }catch(Exception e)
      {
        //写日志
        log("can error");
        return;
      }
      // data+="\nwatch\n";
      //watch
      
      //手表
      String sendAddressWatch="10.0.0.108";
      // String sendAddressWatch="192.168.1.108";
      int sendPort=9996;
      String question = "start";
     
      //通过套接字向客户端发送数据
      try{
        udpSend(question,sendAddressWatch,sendPort);
        String str=udpReceive(8);
        if(!str.equals("ok"))
          return;
      }catch(SocketTimeoutException e){
        log("watch not connect");
        
        // continue;
        return;
      }
      try{
        String str=udpReceive(1024);
        dataWatch=str;
        System.out.println("watch finished");
      }catch(SocketTimeoutException e){
        log("watchData not send");
        return;
      }
      
      //面部疲劳等级和加速度
      
      CloseSocket();
      
      ++index;
      upload(dataRGB,"rgb");
      upload(dataDepth,"depth");
      upload(dataCan,"can");
      upload(dataWatch,"watch");
      
  }
 
  public static String getDate()
  {
      Date date = new Date();
      SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
      String date1 = formatter.format(date);
      return date1;
  }
  public static void upload(String data,String name) throws IOException
  {
    // 上传数据
    try{
      init();
    }catch(Exception e){
      e.printStackTrace();
      log("cloud not connect");
    }
      
      InputStream is = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
      String objectname = name+"/" + getDate() + "-" +(index)+ ".txt";
      try {
        // client.putObject(bucket, objectname,
        //     is, data.length(), "text/plain");
        client.putObject(PutObjectArgs.builder()
					//上传到那个桶中
					.bucket(bucket)
					//指定上传MinIO中后文件叫什么名字
					.object(objectname)
					//指定上传的流
					.stream(is, data.length(), -1)
                    //指定上传的格式,从流中获取到你上传的格式是什么
					.contentType("text/plain")
					.build());
          buckNameList.add(objectname);
        // queue.poll();
      } catch (Exception e){
        // TODO Auto-generated catch block
        //写日志
        //删除写过的文件
        for(int i=0;i<buckNameList.size();++i)
        {
          delete(bucket, objectname);
        }
        log("upload error:"+name);
        e.printStackTrace();
      }
      is.close();
  }
  public static void delete(String bucketName,String objectName) 
  {
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
        } catch (Exception e) {
            log("删除失败");
        }
        log("删除成功");
  }
}
